#ifndef UTIL_H_
#define UTIL_H_

#include <stdint.h>
#include <stddef.h>

uint64_t rand_uint64();

typedef struct {
    size_t size;
    uint8_t *data;
} single_msg, octet_string;

typedef struct {
    size_t num;
    single_msg *msgs;
} multi_msg;

octet_string new_octet_string();
multi_msg new_multi_msg();

void mm_dumps(octet_string *os, const multi_msg *m);
void mm_loads(multi_msg *m, const octet_string *os);

// format: 's' for string (aka. char*), 'd' for 32-bit integer,
// 'k' for key (aka. uint64_t), 'o' for octet_string.
void mm_build(multi_msg *m, const char *format, ...);
void mm_free(multi_msg *m);
void os_free(octet_string *os);

void mm_print(const multi_msg *m);

void mm_sock_write(int fd, const multi_msg *m);
void mm_sock_read(multi_msg *m, int fd);

void mm_dumps_encrypt(octet_string *os, const multi_msg *m, uint64_t key);
void mm_decrypt_loads(multi_msg *m, const octet_string *os, uint64_t key);

#endif
